package com.example.oauth2.authentication.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

/**
 * @author 01
 * @date 2019-05-21
 **/
@Slf4j
//@Configuration
//@EnableAuthorizationServer
public class OAuth2ConfigForMemory extends AuthorizationServerConfigurerAdapter {

    private final AuthenticationManager authenticationManager;
    private final UserDetailsService userDetailsService;

    public OAuth2ConfigForMemory(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) {
        this.authenticationManager = authenticationManager;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("permitAll()")
                .tokenKeyAccess("permitAll()")
                .allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                // 客户端id
                .withClient("example")
                // 客户端密钥
                .secret(new BCryptPasswordEncoder().encode("examplesecret"))
                // 注册重定向url，否则在使用授权码模式时会禁止重定向
                .redirectUris("http://www.baidu.com")
                // 授权模式类型；这里需要注意如果不写refresh_token的话，授权成功后是不会返回refresh_token的
                .authorizedGrantTypes("refresh_token", "password", "authorization_code")
                // access_token有效时间，单位：秒
                .accessTokenValiditySeconds(120)
                // refresh_token有效时间，单位：秒
                .refreshTokenValiditySeconds(160);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }
}
